/*
 * Copyright 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.java

import org.gradle.integtests.fixtures.AbstractIntegrationSpec
import org.gradle.integtests.fixtures.AvailableJavaHomes
import org.gradle.integtests.fixtures.jvm.JavaToolchainFixture
import org.gradle.integtests.fixtures.jvm.TestJavaClassUtil
import org.gradle.internal.FileUtils
import org.gradle.internal.serialize.JavaClassUtil
import org.gradle.test.fixtures.archive.JarTestFixture

/**
 * Tests java compilation across JDK versions.
 */
class JavaCrossCompilationIntegrationTest extends AbstractIntegrationSpec implements JavaToolchainFixture {

    def "can compile java source using java #jdk.javaVersionMajor"() {
        given:
        settingsFile << """
            rootProject.name = 'foo'
        """

        buildFile << """
            plugins {
                id("java-library")
            }

            ${mavenCentralRepository()}
            ${javaPluginToolchainVersion(jdk)}
        """

        file("src/main/java/Thing.java") << """
            public class Thing { }
        """

        when:
        withInstallations(jdk)
        succeeds("compileJava", "jar")

        then:
        new JarTestFixture(file("build/libs/foo.jar")).javaVersion == jdk.javaVersion
        JavaClassUtil.getClassMajorVersion(javaClassFile("Thing.class")) == TestJavaClassUtil.getClassVersion(jdk.javaVersion)

        // Ensure there is no warnings from the JDK, e.g. about illegal access
        outputDoesNotContain("WARNING: ")

        where:
        jdk << AvailableJavaHomes.allJdkVersions
    }

    def "can build and run application using Java #jdk.javaVersionMajor"() {
        given:
        buildFile << """
            plugins {
                id("application")
            }

            ${mavenCentralRepository()}
            ${javaPluginToolchainVersion(jdk)}

            application {
                mainClass = 'Main'
            }
        """

        file("src/main/java/Main.java") << """
            public class Main {
                public static void main(String[] args) {
                    System.out.println("java home: " + System.getProperty("java.home"));
                    System.out.println("java version: " + System.getProperty("java.version"));
                }
            }
        """

        when:
        withInstallations(jdk)
        succeeds("run")

        then:
        output.contains("java home: ${FileUtils.canonicalize(jdk.javaHome)}")
        output.contains("java version: ${jdk.javaVersion}")

        where:
        jdk << AvailableJavaHomes.allJdkVersions
    }

    def "can generate Javadocs using Java #jdk.javaVersionMajor"() {
        given:
        buildFile << """
            plugins {
                id("java-library")
            }

            ${mavenCentralRepository()}
            ${javaPluginToolchainVersion(jdk)}

            // In order to generate the 'Generated by javadoc' output.
            tasks.withType(Javadoc) {
                options.noTimestamp = false
            }
        """

        file("src/main/java/Thing.java") << """
            /** Some thing. */
            public class Thing { }
        """

        when:
        withInstallations(jdk)
        succeeds("javadoc")

        then:
        file('build/docs/javadoc/Thing.html').text.matches("(?s).*Generated by javadoc \\(.*?\\Q${jdk.javaVersion}\\E.*")

        where:
        jdk << AvailableJavaHomes.allJdkVersions
    }
}
